import type { CardListProps } from './types.ts'
import React, { useEffect, useState } from 'react'
import { debounce } from '../../hook/utils.ts'
import Carousel from '../carousel/carousel.tsx'
import './goods-card-list.scss'

interface Position {
  left: number
  top: number
}

const GoodsCardList: React.FC<CardListProps> = ({
  dataList = [],
  maxSales = 5000,
  onClick = () => {},
}) => {
  const [positions, setPositions] = useState<Position[]>([])
  const [columnWidth, setColumnWidth] = useState<number>(0)
  const [maxContainerHeight, setMaxContainerHeight] = useState<number>(0)

  useEffect(() => {
    const updateLayout = () => {
      const container = document.querySelector('.waterfall-container')! as HTMLElement
      if (container) {
        const itemElements = document.querySelectorAll<HTMLElement>('.waterfall-item') as NodeListOf<HTMLElement>
        // 横向间距
        const horizontalGap = 12
        // 纵向间距
        const verticalGap = 10
        const containerWidth = container.offsetWidth
        // 每列宽度为容器宽度的一半减去间距
        const calculatedColumnWidth = (containerWidth - horizontalGap) / 2
        setColumnWidth(calculatedColumnWidth)
        // 两列布局
        const columnHeights = Array.from({ length: 2 }).fill(0) as number[]
        const newPositions: Position[] = []
        // 循环计算所有的子元素的信息
        itemElements.forEach((item) => {
          const { height } = item.getBoundingClientRect()
          // 找到最短的那一列
          const minHeight = Math.min(...columnHeights)
          // 获取该列的索引
          const columnIndex = columnHeights.indexOf(minHeight)
          const left = columnIndex * (calculatedColumnWidth + horizontalGap)
          const top = columnHeights[columnIndex]
          // 存储元素的定位
          newPositions.push({ left, top })
          // 更新该列的高度
          columnHeights[columnIndex] += height + verticalGap
        })
        // 更新位置
        setPositions(newPositions)
        setMaxContainerHeight(Math.max(...columnHeights))
      }
    }
    const debouncedUpdateLayout = dataList.length < 15 ? updateLayout : debounce(updateLayout, 200)
    // 图片加载完成后更新布局
    const handleImageLoad = () => {
      debouncedUpdateLayout()
    }
    // 初始化布局
    debouncedUpdateLayout()
    // 监听图片加载事件，以确保所有图片都加载完后再更新布局
    const images = document.querySelectorAll('.waterfall-container img') as NodeListOf<HTMLImageElement>
    images.forEach((img) => {
      // 如果图片已经加载完成（缓存中加载），则立即更新布局
      if (img.complete) {
        handleImageLoad()
      }
      else {
        // 如果图片未加载完成，监听加载事件
        img.addEventListener('load', handleImageLoad)
      }
    })

    // 窗口变化时更新布局
    window.addEventListener('resize', debouncedUpdateLayout)
    return () => {
      // 清理事件监听
      window.removeEventListener('resize', debouncedUpdateLayout)
      images.forEach(img => img.removeEventListener('load', handleImageLoad))
    }
  },
  // 当 dataList 变化时重新计算
  [dataList])

  return (
    <>
      <div
        className="card-list-goods__container waterfall-container"
        style={{
          height: `${maxContainerHeight + 20}px`,
        }}
      >
        {dataList.map((item, index) => (
          <div
            key={item.key}
            className="card-list-goods__item waterfall-item"
            onClick={() => onClick(item)}
            style={{
              left: `${positions[index]?.left}px`,
              top: `${positions[index]?.top}px`,
              width: `${columnWidth}px`,
            }}
          >
            {
              item.imageList && item.imageList.length > 0 && (
                <div className="card-list-goods__image">
                  <Carousel
                    images={item.imageList}
                    interval={3000}
                  />
                </div>
              )
            }
            <div className="card-list-goods__content">
              <div className="card-list-goods__title">{item.title}</div>
              <div className="card-list-goods__desc">{item.desc}</div>
              <div className="card-list-goods__bottom">
                <div className="card-list-goods__unit">￥</div>
                <div className="card-list-goods__price">{item.activePrice || item.price}</div>
                {
                  item.activePrice && <div className="card-list-goods__unit__delete">￥</div>
                }
                {
                  item.activePrice && <div className="card-list-goods__price__delete">{item.price}</div>
                }
                <div className="card-list-goods__sales">
                  已售
                  {item.sales > maxSales ? `${maxSales}+` : item.sales}
                </div>
              </div>
            </div>
          </div>
        ))}
      </div>
    </>
  )
}

GoodsCardList.displayName = 'GoodsCardList'
export default GoodsCardList
